#include "PbConvertor.h"
#include <fstream>
#include <iostream>
#include "Cdd_IpcfShm_Platform.pb.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define SOCKET_PATH "/tmp/unix_dgram_socket"

#if 0
void test_demo()
{
    // testBox testMessage;

    // testData testChildMessage;
    // testChildMessage.b = 1;
    // testChildMessage.c = 2;
    // testChildMessage.d = 3;
    // int32_t array[4] = {1,2,3,4};
    // testChildMessage.e = array;

    // testMessage.data = testChildMessage;

    testNamespace::TestMessage testMessage;

    testMessage.doubleField = 1.234;
    // testMessage.floatField = 1.23;
    testMessage.int32Field = -123;
    testMessage.int64Field = -1234;
    testMessage.uint32Field = 123;
    // testMessage.uint64Field = 1234;
    testMessage.boolField = true;
    testMessage.stringField = "Hello, 科比.布莱恩特.";
    testMessage.testEnumField = testNamespace::enum3;

    double arr1[3] = {1.234, 5.678, 9.101112};
    testMessage.repeatedDoubleField = arr1;
    testMessage.repeatedStringLengthField = 3;

    char *pSerializedPb;
    size_t serializedPbSize;
    if (PbConvertor::struct2serializedPb((const char *)&testMessage, "testPackage.TestMessage", pSerializedPb, serializedPbSize))
    {
        testPackage::TestMessage testMessagePb;
        // box testMessagePb;
        bool bRet = testMessagePb.ParseFromArray(pSerializedPb, serializedPbSize);

        std::fstream ofs("test.pb.txt", std::ios::out | std::ios::trunc);
        
        if(ofs.is_open()) {
            testMessagePb.SerializeToOstream(&ofs);
        }
        ofs.close();
        // printf("b:%d, c:%d, d:%lf, e:%d\n", testMessagePb.data().b(), testMessagePb.data().c(), testMessagePb.data().d(), testMessagePb.data().e(2));
        printf("b:%lf, c:%lf, d:%lf\n", testMessagePb.repeateddoublefield(0), testMessagePb.repeateddoublefield(1), testMessagePb.repeateddoublefield(2));

        PbConvertor::MemTree stru;
        if (PbConvertor::serializedPb2struct("testPackage.TestMessage", pSerializedPb, serializedPbSize, stru))
        {
            testNamespace::TestMessage *pTestMessage = (testNamespace::TestMessage *)stru.pMem;
            // printf("b:%d, c:%d, d:%lf, e:%d\n", pTestMessage->data.b, pTestMessage->data.c, pTestMessage->data.d, pTestMessage->data.e[2]);
            printf("b:%lf, c:%lf, d:%lf\n", testMessagePb.repeateddoublefield(0), testMessagePb.repeateddoublefield(1), testMessagePb.repeateddoublefield(2));
            stru.release();
        }
        delete [] pSerializedPb;
    }
}

#endif

void test_VDU()
{
  int socketfd = socket(AF_UNIX, SOCK_DGRAM, 0);
  if (socketfd == -1) {
    perror("socket");
    exit(EXIT_FAILURE);
  }

  struct sockaddr_un server_addr, client_addr;
  memset(&server_addr, 0, sizeof(struct sockaddr_un));
  server_addr.sun_family = AF_UNIX;
  strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

  // 绑定套接字到地址
  if (bind(socketfd, (struct sockaddr *)&server_addr,
           sizeof(struct sockaddr_un)) == -1) {
    perror("bind");
    close(socketfd);
    exit(EXIT_FAILURE);
  }

  socklen_t client_len;
  while (1) {
    char recvbuf[5*1024] = {0};
    int ret = recvfrom(socketfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*)&client_addr, &client_len);
    if (ret == -1) {
        perror("recvfrom");
        close(socketfd);
        exit(EXIT_FAILURE);
    }
    printf("recv success ret:%d\n",ret);

    char *pSerializedPb;
    size_t serializedPbSize;
    if (PbConvertor::struct2serializedPb((const char *)recvbuf, "Cdd_IpcfShm.Cdd_IpcfPbMsg_Data_Acquire_M2A", \
         pSerializedPb, serializedPbSize)) {
        Cdd_IpcfShm::Cdd_IpcfPbMsg_Data_Acquire_M2A testMessagePb;
        bool bRet = testMessagePb.ParseFromArray(pSerializedPb,serializedPbSize); 
        printf("msgid:%d, timesec:%d, batteryinfo[1]:%d,batteryinfo[479]:%d\n",
        testMessagePb.mutable_ipcfchanl_header()->mesg_id(),testMessagePb.mutable_ipcfchanl_header()->timestamp_sec(),
        testMessagePb.main_battery_info_data()[1],
        testMessagePb.main_battery_info_data()[479]);
    }
  }
}

int main()
{
    // test_demo();
    test_VDU();

    return 0;
}